#include "../include/MoteurGraphique.h"


MoteurGraphique::MoteurGraphique( int res, Monde& m) : monde(m)
{
	// intialisation de la variable encours
	encours = true;

	// initialisation selection
	selectionEnCours = false; 

	cheminDonnees = "./donnees/images/";
	
	sf::VideoMode mode;
	if( res == 1)
		mode = sf::VideoMode(1024, 768, 32);
	else if( res == 2 )
		mode = sf::VideoMode(1280, 800, 32);
	else if( res == 3 )
		mode = sf::VideoMode(1600, 900, 32);
	else if( res == 0 )
		mode = sf::VideoMode(800, 600, 32);

	 App = new sf::RenderWindow(mode, "AOE",sf::Style::Close,sf::WindowSettings(24,8,16));
	
	#if VERBOSE
		std::cout<<"Creation fenetre graphique... done"<<std::endl;
	#endif

	if( icone.LoadFromFile(cheminDonnees+"icone.jpg") ) 
		App->SetIcon(icone.GetWidth(), icone.GetHeight(), icone.GetPixelsPtr());


	#if VERBOSE
		std::cout<<"Creation d'une icone... done"<<std::endl;
	#endif


	#if LOLILOL

		// ma pub :)	
		viewerDiscretion();

		// chargement
		chargerRessourcesMenu();

		// affichage menu
		menu();
	#endif

	affichageJeu = new AfficherJeu(App, cheminDonnees, m);
	

	// initialisation compteur frame

}
void MoteurGraphique::viewerDiscretion()
{
	// on efface l'écran
	clear();

	// création de la police de caractère
	sf::Font MyFont;

	// Chargement à partir d'un fichier sur le disque
	if (!MyFont.LoadFromFile("opens.ttf",60))
	{
	   std::cout<<"Erreur au chargement de la police"<<std::endl;
	   return;
	}

	// création des textes
	sf::String Text1("This is a Developper Preview.", MyFont,55);
	sf::String Text2("Content comes without any warranty.", MyFont,55);
	sf::String Text3("Viewer discretion is advised.", MyFont,55);

	// placement /!\ Doit etre dynamique !!!!
	Text1.Move(100.f, 200.f);
	Text2.Move(100.f, 260.f);
	Text3.Move(100.f, 320.f);

	// Efface l'écran (remplissage avec du noir)
	App->Clear();

	// Affichage progressif
	for( int i=0; i!=255; i+=5)
	{
		clear();
		Text1.SetColor(sf::Color(255,255, 255, i));
		App->Draw(Text1);
		App->Display();
		tempo( GRAP_DEVELOPPER_PREVIEW_TEXT_TIME);
	}
	tempo( 500);
	// Affichage progressif
	for( int i=0; i!=255; i+=5)
	{
		clear();
		Text2.SetColor(sf::Color(255,255, 255, i));
		App->Draw(Text1);
		App->Draw(Text2);
		App->Display();
		tempo( GRAP_DEVELOPPER_PREVIEW_TEXT_TIME);
	}
	tempo( 500);
	// Affichage progressif
	for( int i=0; i!=255; i+=5)
	{
		clear();
		Text3.SetColor(sf::Color(255,255, 255, i));
		App->Draw(Text1);
		App->Draw(Text2);
		App->Draw(Text3);
		App->Display();
		tempo( GRAP_DEVELOPPER_PREVIEW_TEXT_TIME);
	}
	tempo( 500);

	#if VERBOSE
		std::cout<<"Developper Preview... done"<<std::endl;
	#endif  
	
}	
void MoteurGraphique::clear()
{
	App->Clear();
}

void MoteurGraphique::tempo( int ms)
{
	struct timespec a;
	a.tv_sec = (int)ms/1000;
	a.tv_nsec = (float)ms*1000000;
	nanosleep(&a,&a);
}
void MoteurGraphique::chargerRessourcesMenu()
{
	clear();

	// création de la police de caractère
	sf::Font MyFont;

	// Chargement à partir d'un fichier sur le disque
	if (!MyFont.LoadFromFile("opens.ttf",60))
	{
	   std::cout<<"Erreur au chargement de la police"<<std::endl;
	   return;
	}
	
	sf::String Text1("Loading ...", MyFont,55);
	sf::String Text2("|", MyFont,55);
	Text1.Move(100.f, 260.f);
	Text2.Move(500.f, 300.f);

	for( int i=0; i<=100; i++)
	{
		//clear();
		Text2.Rotate(7);
		tempo( GRAP_DEVELOPPER_PREVIEW_TEXT_TIME/2);
		App->Draw(Text1);
		App->Draw(Text2);
		App->Display();
	}

	#if VERBOSE
		std::cout<<"Chargement menu... done"<<std::endl;
	#endif
}

void MoteurGraphique::menu()
{
	clear();
	sf::Image fond_image;
	if (!fond_image.LoadFromFile(cheminDonnees+"intro.jpg"))
	{
	    // Erreur...
		return;
	}
	sf::Sprite fond;
	fond.SetImage(fond_image);
	fond.Resize(App->GetWidth(), App->GetHeight());
	App->Draw(fond);
	App->Display();

	tempo( 5000);

}

int MoteurGraphique::getChoix()
{
	return 0;
}

void MoteurGraphique::render( )
{	
	clear();
	/***** Utilisation d'une vue de dessus *******/

	affichageJeu->render();

	gererEvents();

	affichageJeu->afficherSelectionnes();

	App->Display();

		// Traitement des évènements
	/*sf::Event Event;
		while (App->GetEvent(Event))
		{
		    // Fenêtre fermée : on quitte
		    if (Event.Type == sf::Event::Closed)
		    {
		        App->Close();
			encours = false;
		    }
		}*/

	//sf::Shape villageois_s = sf::Shape::Rectangle(X1, Y1, X2, Y2, Couleur, [Bordure], [CouleurBordure]);
	//sf::Shape forum_s = sf::Shape::Rectangle(X1, Y1, X2, Y2, Couleur, [Bordure], [CouleurBordure]);
}
void MoteurGraphique::attendreFin()
{
	    while (App->IsOpened())
   	 {
		// Traitement des évènements
		sf::Event Event;
		while (App->GetEvent(Event))
		{
		    // Fenêtre fermée : on quitte
		    if (Event.Type == sf::Event::Closed)
		        App->Close();
		}
	}
}

void MoteurGraphique::gererEvents()
{

		sf::Event Event;
		while (App->GetEvent(Event))
		{
			// Fenêtre fermée : on quitte
			if (Event.Type == sf::Event::Closed){
			App->Close();
			encours = false;
			}
			// Clic gauche TODO: Verifier que le curseur est pas sur le HUD
			if( Event.Type == sf::Event::MouseButtonPressed && Event.MouseButton.Button == sf::Mouse::Left )
			{
				selectionEnCours = true;
				debutSelectionPosition.x = Event.MouseButton.X;	
				debutSelectionPosition.y = Event.MouseButton.Y;
				#if DEBUG_MOUSE
					std::cout<<"Debut click : "<<Event.MouseButton.X<<" | "<<Event.MouseButton.Y<<std::endl;
				#endif
			}
			/// Clic gauche & selection en cours
			if(Event.Type == sf::Event::MouseButtonReleased && selectionEnCours)
			{
				// On arrete la prise en compte de zone
				selectionEnCours = false;
	
				// On  cree le bloc selectionne
				Taille t;
				Position p;
				if( debutSelectionPosition.x < Event.MouseButton.X )
				{
					p.x = debutSelectionPosition.x;
				}
				else
				{
					p.x = Event.MouseButton.X;
				}
				if( debutSelectionPosition.y < Event.MouseButton.Y )
				{
					p.y = debutSelectionPosition.y;
				}
				else
				{
					p.y = Event.MouseButton.Y;
				}
				t.x = fabs( debutSelectionPosition.x - Event.MouseButton.X); 
				t.y = fabs( debutSelectionPosition.y - Event.MouseButton.Y); 
		
				blocSelection.setTaille(t);
				blocSelection.setPosition(p);

				// On passe le bloc obtenu à la classe qui le gere
				affichageJeu->selectionner(blocSelection);				

				// 
				#if DEBUG_MOUSE
					std::cout<<"Fin click"<<std::endl;
				#endif
			}
			/// Clic droit
			if( Event.Type == sf::Event::MouseButtonPressed && Event.MouseButton.Button == sf::Mouse::Right )
			{
				// Si on a des unites de selectionnees
				if( affichageJeu->getBatimentSelectionne() != NULL || affichageJeu->getEntiteSelectionne(0) != NULL )
				{
					Position p;
					Taille t;
					p.x =  Event.MouseButton.X;
					p.y =  Event.MouseButton.Y;
					t.x = 1;
					t.y = 1;
					Bloc b(p,t);

					Element* e = affichageJeu->getSelectionne( b);
	
					// Si on a cliqué sur rien et que l'on avait pas selecionne de batiment
					if( e == NULL && affichageJeu->getBatimentSelectionne() == NULL  )
					{
						unsigned int i=0;
						while( affichageJeu->getEntiteSelectionne(i) != NULL )
						{
							monde.creerOccupation( affichageJeu->getEntiteSelectionne(i), p );
							i++;
						}
					}
					// Si on a cliqué sur un element
					if( e != NULL && affichageJeu->getBatimentSelectionne() == NULL  )
					{
						unsigned int i=0;
						while( affichageJeu->getEntiteSelectionne(i) != NULL )
						{
							monde.creerOccupation( affichageJeu->getEntiteSelectionne(i), e );
							i++;
						}
					}

	
				}			
			}
		}
		
		// Pour plus de rapidité dans la gestion des touches
		const sf::Input& Input = App->GetInput();

		// Si on a une zone de selection en cours
		if( selectionEnCours )
		{
			creerZoneSelection( debutSelectionPosition, Bloc::creerPosition((float)Input.GetMouseX(),(float)Input.GetMouseY()));
			#if DEBUG_MOUSE
				std::cout<<p.x<<"|"<<p.y<<std::endl;
			#endif
		}
}

bool MoteurGraphique::enCours()
{
	return encours;
}

void MoteurGraphique::creerZoneSelection( Position debut, Position fin)
{
	sf::Shape Rectangle =  sf::Shape::Rectangle(debut.x,debut.y,fin.x,fin.y, sf::Color::White);
	Rectangle.SetColor(sf::Color(255,255, 255, 128));
		App->Draw(Rectangle);
}
/*
void MoteurGraphique::afficherSelectionnes( Monde &m)
{
	if( selectionEnCours )
		return;

	std::vector<Entite*> entites = m.getEntites();
	for(unsigned int i=0; i<entites.size(); i++)
	{
		if( Carte::collision( blocSelection, *(entites[i])))
		{
			// traiter
			#if DEBUG
			std::cout<<"collision en X:"<<Carte::estAligneX(blocSelection, *(entites[i]))<<std::endl;
			std::cout<<"collision en Y:"<<Carte::estAligneY(blocSelection, *(entites[i]))<<std::endl;
			std::cout<<"Collision detectee sur zone de selection :"<<blocSelection.getPosition()->x<<"-"<<blocSelection.getTaille().x<<std::endl;
			std::cout<<"Collision detectee sur zone de selection :"<<(*(entites[i])).getPosition()->x<<"-"<<(*(entites[i])).getTaille().x<<std::endl;
			#endif
		}
	}
}*/
